package com.benefm.multipar.pad;

import android.util.Log;

import com.benefm.multipar.pad.event.EventAction;
import com.benefm.multipar.pad.event.MsgEvent;
import com.benefm.multipar.pad.mqtt.MqttAndroidClient;

import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.greenrobot.eventbus.EventBus;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MqttManager {

    public static final String TAG = MqttManager.class.getSimpleName();

    private MqttAndroidClient client;
    private MqttConnectOptions conOpt;

    public static final String SERVER_URI = "tcp://119.23.200.81:21883";
    public static final String USERNAME = "admin";
    public static final String PASSWORD = "Benefm@2022";

    public static final String SERVER_URI_TEST = "tcp://39.108.146.253:1883";
    public static final String USERNAME_TEST = "benefm2025";
    public static final String PASSWORD_TEST = "O4^PVhqnz26OE^bk";

    public static final String TOPIC_DEVICE_DATA = "mss/public/";

    private final ExecutorService executor = Executors.newSingleThreadExecutor();

    private String clientId, mac;

    public MqttManager(String mac) {
        this.mac = mac;
        clientId = "bmecg_android" + mac;
    }

    public void initMqtt() {
        client = new MqttAndroidClient(BaseApp.getInstance(), BaseApp.isDebug ? SERVER_URI_TEST : SERVER_URI, clientId);
        client.setCallback(mqttCallback);
        conOpt = new MqttConnectOptions();
        // 清除缓存
        conOpt.setCleanSession(true);
        // 设置超时时间，单位：秒
        conOpt.setConnectionTimeout(30);
        // 心跳包发送间隔，单位：秒
        conOpt.setKeepAliveInterval(60);
        // 用户名
        conOpt.setUserName(BaseApp.isDebug ? USERNAME_TEST : USERNAME);
        // 密码
        conOpt.setPassword(BaseApp.isDebug ? PASSWORD_TEST.toCharArray() : PASSWORD.toCharArray());

        connect();
    }


    public void connect() {
        if (client != null && !client.isConnected()) {
            try {
                if (BaseApp.isDebug)
                    Log.i(TAG, "MQTT开始尝试连接....");
                client.connect(conOpt, null, iMqttActionListener);
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
    }

    public void disconnect() {
        executor.shutdown();
        if (client != null && client.isConnected()) {
            try {
                client.disconnect();
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
    }

    public boolean isConnect() {
        return client != null && client.isConnected();
    }

    public void subscribeTopic(String mac) {
        if (client != null && client.isConnected()) {
            String topic = TOPIC_DEVICE_DATA + mac.replace(":", "");
            System.out.println("[subscribe topic] " + topic);
            try {
                client.subscribe(topic, 0);
            } catch (MqttException e) {
                e.printStackTrace();
            }
        } else {
            if (BaseApp.isDebug)
                Log.e(TAG, "订阅失败,MQTT未连接或者为NULL......");
        }

    }


    public void unsubscribeTopic() {
        if (client != null && client.isConnected()) {
            String topic = TOPIC_DEVICE_DATA + mac.replace(":", "");
            System.out.println("[unsubscribe topic] " + topic);
            try {
                client.unsubscribe(topic);
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
    }


    private final MqttCallback mqttCallback = new MqttCallback() {
        @Override
        public void connectionLost(Throwable cause) {
            if (BaseApp.isDebug)
                Log.e(TAG, "MQTT失去连接!");
            EventBus.getDefault().post(new MsgEvent<>(EventAction.MSG_MQTT_DISCONNECT, mac));
        }


        @Override
        public void deliveryComplete(IMqttDeliveryToken token) {

        }

        @Override
        public void messageArrived(String topic, MqttMessage message) {
            byte[] data = message.getPayload();
//            Log.i(TAG, "[mqtt received " + data.length + "]" + StringUtil.toHexString(data, " "));
            executor.execute(new MqttHandleThread(data));
        }
    };

    private final IMqttActionListener iMqttActionListener = new IMqttActionListener() {
        @Override
        public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
            if (BaseApp.isDebug)
                Log.e(TAG, "-------MQTT连接失败!--------");
            exception.printStackTrace();
            EventBus.getDefault().post(new MsgEvent<>(EventAction.MSG_MQTT_DISCONNECT, mac));
        }

        @Override
        public void onSuccess(IMqttToken asyncActionToken) {
            if (BaseApp.isDebug)
                Log.i(TAG, "======MQTT连接成功!======");
            subscribeTopic(mac);
            EventBus.getDefault().post(new MsgEvent<>(EventAction.MSG_MQTT_CONNECT, mac));
        }
    };


}
